home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / sco / scripts / ppmbrowse < prev    next >
Encoding:
Korn shell script  |  1997-08-26  |  11.3 KB  |  371 lines

  1. #!/bin/ksh
  2. # @(#) ppmbrowse.ksh 1.1 96/11/27
  3. # 94/04/02 john h. dubois iii (john@armory.com)
  4. # 95/02/07 Insist that output not be a tty.
  5. # 96/01/19 Make default tmpdir be home dir for safety
  6. # 96/11/27 Added jIG options.  Let input files be gif or jpeg.
  7.  
  8. alias istrue="test 0 -ne"
  9. alias isfalse="test 0 -eq"
  10.  
  11. name=${0##*/}
  12. Usage=\
  13. "Usage: $longname [-hmxgGjpP] [-c<columns>] [-b<background-color>] [-s<size>]
  14.     [-B<border-width>] [-H<horizontal-separation>] [-V<vertical-separation>]
  15.     [-t<text-color>] [-q<quantized-colors>] [-[iI]<image-map-format-string>]
  16.     [-S<separation>] [-f<image-map-file>] image [image ...] > browser-file"
  17.  
  18. Background=blue
  19. Text=white
  20. noExt=false
  21. progress=false
  22. typeset -i Vertical=2 Horizontal=5 Colors=0 Columns=6 Size=100 Debug=0
  23. typeset -i Border=5 Preserve=0 MakeMap=0
  24.  
  25. typeset -i InfX InfY
  26. function pnminfo {
  27.     typeset j1 j2 j3 j4
  28.     [ $# -gt 0 ] && pnmfile "$1" | read j1 type j2 InfX j3 InfY j4 ||
  29.      pnmfile | read j1 type j2 InfX j3 InfY
  30. }
  31.  
  32. # Usage: GetUnCom filename.ext
  33. # Sets global getUnCom_ret to the name of an uncompressor appropriate for the
  34. # given file, based on its extension.  If no appropriate uncompressor is known,
  35. # getUnCom_ret is set to a null string.
  36. function getUnCom {
  37.     case "${1##*.}" in
  38.     [jJ][pP]?([eE])[gG])
  39.     getUnCom_ret=djpeg
  40.     ;;
  41.     [gG][iI][fF])
  42.     getUnCom_ret=giftopnm
  43.     ;;
  44.     [pP][bBgGpPnN][mM])
  45.     getUnCom_ret=cat
  46.     ;;
  47.     *)
  48.     getUnCom_ret=
  49.     ;;
  50.     esac
  51. }
  52.  
  53. # Usage: topnm filename [command [args]]
  54. # A converter to pnm format is chosen based on the filename extension.
  55. # If a command is given, the output of the converter is piped into it;
  56. # otherwise it is sent to the standard output.
  57. # As an optimization, if the file is already in pnm format and a command is
  58. # given, it is passed as the final argument to command.  Therefore, a command
  59. # should only be given if it is appropriate to pass it a pnm file after all
  60. # of its fixed arguments.
  61. # The global DEF_EXT provides a default for files with unknown extensions.
  62. function topnm {
  63.     typeset uncom= ext filename=$1
  64.     shift
  65.  
  66.     getUnCom "$filename"
  67.     [ -z "$getUnCom_ret" -a -n "$DEF_EXT" ] && getUnCom "$DEF_EXT"
  68.     if [ -z "$getUnCom_ret" ]; then
  69.     print -u2 -- \
  70.     "$longname: Do not know what to do with a '.${filename##*.}' file."
  71.     return 1
  72.     fi
  73.     if [ $# -gt 0 ]; then
  74.     [ "$getUnCom_ret" = cat ] && "$@" "$filename" ||
  75.     "$getUnCom_ret" < "$filename" | "$@"
  76.     else
  77.     "$getUnCom_ret" < "$filename"
  78.     fi
  79.     return $?
  80. }
  81.  
  82. # Usage: MakeRow file ....
  83. # Uses globals: HSepFile (horizontal separator), Debug, Row, Tmp, Horizontal,
  84. # MapStr
  85. # Adds new row file to RowFiles[].
  86. # Runs PrintMap if making image map.
  87. function MakeRow {
  88.     typeset Files file RowTmp
  89.  
  90.     # If any horizontal separtion, add it in
  91.     if istrue Horizontal; then
  92.     Files=$1
  93.     shift
  94.     for file; do
  95.         Files="$Files $HSepFile $file"
  96.     done
  97.     else
  98.     Files=$*
  99.     fi
  100.     let Row+=1
  101.     RowTmp=$Tmp.r.$Row.$$
  102.     RowFiles[Row]=$RowTmp
  103.     istrue Debug && print -u2 "Row: $Row.  RowFile: $RowTmp.  Files: $Files."
  104.     pnmcat -lr $Files > $RowTmp
  105.     istrue MakeMap && PrintMap $Row
  106. }
  107.  
  108. # Usage: PrintMap row
  109. # Write image map file to fd 3
  110. # Globals: 
  111. # FileNames[]    Base names of files in this row
  112. # MapStr    Proto-URL
  113. # Vertical    Vertical separation between images
  114. # Horizontal    Horizonal separation between images
  115. # Size        Width of map area
  116. # ThumbYDim    Height of map area
  117. # Border    Width of border
  118. # Columns    Number of columns in widest row
  119. function PrintMap {
  120.     typeset -i Row=$1 Left=Border Right Bottom Top XShift ColNum=0 NFiles
  121.     typeset file MapOut
  122.     
  123.     NFiles=${#FileNames[*]}
  124.     if [ NFiles -lt Columns ]; then
  125.     let Left+="(Columns-NFiles)*(Size+Horizontal)/2"
  126.     fi
  127.     Top="(Row-1)*(Vertical+ThumbYDim)+Border"
  128.     Bottom=Top+ThumbYDim-1
  129.     for file in "${FileNames[@]}"; do
  130.     Right=Left+Size-1
  131.     Replace %s "$file" "$MapStr"
  132.     MapOut="rect $Replace_return $Left,$Top $Right,$Bottom"
  133.     istrue Debug && print -u2 "Image map string: $MapOut"
  134.     print "$MapOut" >&3
  135.     Left=Right+Horizontal+1
  136.     done
  137.     unset FileNames[*]
  138. }
  139.  
  140. # Usage: Replace <repl> <with> <string>
  141. # Replaces the first instance of <repl> in <with> with <string> and assigns the
  142. # result to Replace_return.
  143. function Replace {
  144.     Replace_return="${3%%$1*}$2${3#*$1}"
  145. }
  146.  
  147. # Usage: MakeBr file ....
  148. # Uses globals: VSepFile (vertical separator), Debug, Vertical
  149. function MakeBr {
  150.     typeset Files file
  151.  
  152.     # If any Vertical separtion, add it in
  153.     if istrue Vertical; then
  154.     Files=$1
  155.     shift
  156.     for file; do
  157.         Files="$Files $VSepFile $file"
  158.     done
  159.     else
  160.     Files=$*
  161.     fi
  162.     istrue Debug && print -u2 "Files: $Files."
  163.     pnmcat -tb $Files
  164. }
  165.  
  166. set -e    # Exit if non-num parm assigned to integer var
  167. while getopts :hc:b:t:S:V:H:q:s:xPf:i:I:mgGpj opt; do
  168.     case $opt in
  169.     h)
  170.     echo \
  171. "$longname: make an image browser from a group of image files.
  172. $longname makes a single image containing thumbnail versions of each named
  173. image file, with a label under each, and writes it to the standard output.
  174. $Usage
  175. Options:
  176. -h: Print this help.
  177. -x: Turn on debugging.
  178. -P: Preserve (do not remove) tmp files.
  179. -c: Set the number of images in each row.  The default is $Columns.
  180. -b: Set the background color.  The default is $Background.
  181. -B: Set the border width.  The default is $Border pixels.
  182. -t: Set the text color.  The default is $Text.
  183. -V: Set the separation between rows.  The default is $Vertical pixels.
  184. -H: Set the separation between columns.  The default is $Horizontal pixels.
  185. -S: Set both the horizontal and vertical separation.
  186. -q: Set the number of colors the final image is quantized to.
  187.     The default is no quantization.
  188. -s: Set the size of the thumbnail images.  The default is $Size pixels.
  189.     If the largest dimension of the image is smaller than the given size,
  190.     it is not scaled.  If it is larger, the image is scaled so that its
  191.     largest dimension is equal to the given size.
  192. -i: Create a www-style image map for the browser.  The string given with -i
  193.     should be a URL, with a %s where the base name of the file (the filename
  194.     with its leading path components removed) should be substituted in.  A
  195.     default line with \"nosel.html\" substituted for %s will be put at the top.
  196.     Example: -ihttp://www.armory.com./~spcecdt/%s
  197.     If -F is given and -i is not, %s by itself is used.
  198. -I: Like -i except that the extension (if any) is removed from the filename
  199.     before it is substituted for %s.  This allows the browser to be constructed
  200.     from files with a different extension than the ones that will be made
  201.     available to a web server.
  202.     Example: -Ihttp://www.armory.com./~spcecdt/%s.jpg
  203. -f: Specify an output file for the image map.  If -i is given and -f is not,
  204.     the image map will be written to the file browser.map.
  205. -g: Produce output in GIF format.
  206. -j: Produce output in JPEG format.
  207. -p: Produce output in ppm format (default).
  208. -G: Print a progress indication to the standard error output.  As each file is
  209.     about to be processed, its name is printed.
  210. -m: Set the defaults for certain options to those appropriate for an image map.
  211.     Quantization is set to 240 colors, an image map is produced with defaults
  212.     as described for -i and -f, and the output is in GIF format.
  213.     Options given later on the command line can override these."
  214.  
  215.     exit 0
  216.     ;;
  217.  
  218.     c)  Columns=OPTARG;;
  219.     b)  Background=$OPTARG;;
  220.     t)  Text=$OPTARG;;
  221.     V)  Vertical=OPTARG;;
  222.     H)  Horizontal=OPTARG;;
  223.     S)  Vertical=OPTARG Horizontal=OPTARG;;
  224.     q)  Colors=OPTARG;;
  225.     s)  Size=OPTARG;;
  226.     x)  Debug=1;;
  227.     P)  Preserve=1;;
  228.     i)  MapStr=$OPTARG MakeMap=1;;
  229.     I)  MapStr=$OPTARG MakeMap=1 noExt=true;;
  230.     f)  MapFile=$OPTARG MakeMap=1;;
  231.     g)  OutputConvert=ppmtogif;;
  232.     G)  progress=true;;
  233.     j)  OutputConvert=cjpeg;;
  234.     p)  unset OutputConvert;;
  235.     m)  Colors=240 MakeMap=1 OutputConvert=ppmtogif;;
  236.     +?)
  237.     print -u2 "$longname: options should not be preceded by a '+'."
  238.     exit 1
  239.     ;;
  240.     :) 
  241.     print -r -u2 -- \
  242.     "$longname: Option '$OPTARG' requires a value.  Use -h for help."
  243.     exit 1
  244.     ;;
  245.     ?) 
  246.     print -u2 "$longname: $OPTARG: bad option.  Use -h for help."
  247.     exit 1
  248.     ;;
  249.     esac
  250. done
  251.  
  252. set +e
  253.  
  254. if [ -t 1 ]; then
  255.     print -u2 \
  256. "The standard output should be a file, not a tty,
  257. because the browser image is written to it.  Aborting." 
  258.     exit 1
  259. fi
  260.  
  261. # remove args that were options
  262. let OPTIND=OPTIND-1
  263. shift $OPTIND
  264.  
  265. if [ $# -lt 1 ]; then
  266.     print -u2 "$Usage\nUse -h for help."
  267.     exit
  268. fi
  269.  
  270. typeset -i NumFiles=$# Rows Size XDim YDim LabelHeight ThumbXOff LabelXOff
  271. typeset -i LabelX LabelY ThumbYOff LabelYOff ThumbYDim Column=0 Row=0
  272.  
  273. Rows="(NumFiles+Columns-1)/Columns"
  274. XDim="Border*2+(Columns-1)*Vertical+Columns*Size"
  275. YDim="Border*2+(Rows-1)*Horizontal+Rows*Size"
  276.  
  277. # Quit if anything fails
  278. set -e
  279.  
  280. # Labels come out different heights, but this is good enough
  281. pbmtext XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  | pnminfo
  282. LabelHeight=InfY
  283. FontWidth=InfX/40
  284. typeset -L$((Size/FontWidth-2)) Label
  285.  
  286. istrue Debug && print -u2 \
  287. "NumFiles=$NumFiles Rows=$Rows XDim=$XDim YDim=$YDim LabelHeight=$LabelHeight"
  288.  
  289. : ${TMP:=$TMPDIR}
  290. : ${TMP:=$HOME}
  291. Tmp=${TMP:-/tmp}/#ppb
  292. ThumbBack=$Tmp.tb.$$
  293. ThumbTmp=$Tmp.t.$$
  294. LTmp=$Tmp.l.$$
  295. HSepFile=$Tmp.hs.$$
  296. VSepFile=$Tmp.vs.$$
  297. isfalse Preserve && 
  298. trap "rm -f $ThumbBack $ThumpTmp $ThumpLTmp $LTmp $Tmp.t.+([0-9]).$$ "\
  299. "$VSepFile $HSepFile $Tmp.r.+([0-9]).$$ $ThumbTmp; exit" EXIT 1 2 3 15
  300.     
  301.  
  302. # Create background for image part of one element
  303. ThumbYDim=Size+LabelHeight
  304. ppmmake $Background $Size $ThumbYDim > $ThumbBack
  305.  
  306. if istrue Debug; then
  307.     pnminfo $ThumbBack
  308.     print -u2 "Made $InfX x $InfY background."
  309. fi
  310.  
  311. # Create horizontal separator if it will be needed
  312. istrue Horizontal && ppmmake $Background $Horizontal $ThumbYDim > $HSepFile
  313.  
  314. # Create vertical separator if it will be needed
  315. if istrue Vertical; then
  316.     typeset -i TotWidth="Size*Columns+Horizontal*(Columns-1)"
  317.  
  318.     istrue Debug && print -u2 "Making $TotWidth x $Vertical vertical separator"
  319.     ppmmake $Background $TotWidth $Vertical > $VSepFile
  320. fi
  321.  
  322. if istrue MakeMap; then
  323.     [ -z "$MapStr" ] && MapStr=%s
  324.     [ -z "$MapFile" ] && MapFile=browser.map
  325.     # Make fd 3 be the map output file
  326.     exec 3>"$MapFile"
  327.     Replace %s "$file" nosel.html
  328.     print -r "default $Replace_return" >&3
  329. fi
  330.  
  331. for file; do
  332.     $progress && print -ru2 -- "$file"
  333.     # Make label file
  334.     Label=${file%.*}
  335.     pbmtext $Label | pgmtoppm $Text-$Background > $LTmp
  336.     pnminfo $LTmp
  337.     LabelX=InfX
  338.     LabelY=InfY
  339.     # Make thumbnail file
  340.     topnm "$file" pnmscale -xysize $Size $Size > $ThumbTmp
  341.     pnminfo $ThumbTmp
  342.     ThumbXOff="(Size-InfX)/2"
  343.     ThumbYOff=Size-InfY
  344.     LabelXOff="(Size-LabelX)/2"
  345.     LabelYOff="ThumbYDim-LabelY"
  346.     istrue Debug && print -u2 \
  347. "Thumbnail is $InfX x $InfY.  Label is $LabelX x $LabelY.
  348. Pasting thumbnail in at x offset $ThumbXOff, y offset $ThumbYOff.
  349. Pasting label in at x offset $LabelXOff, y offset $LabelYOff."
  350.     let Column+=1
  351.     ThumbLTmp=$Tmp.t.$Column.$$
  352.     ThumbFiles[Column]=$ThumbLTmp
  353.     # For the image map
  354.     $noExt && FileNames[Column]=${file%.*} || FileNames[Column]=$file
  355.     pnmpaste -replace $ThumbTmp $ThumbXOff $ThumbYOff $ThumbBack |
  356.     pnmpaste -replace $LTmp $LabelXOff $LabelYOff > $ThumbLTmp
  357.     if [ Column -eq Columns ]; then
  358.     MakeRow "${ThumbFiles[@]}"
  359.     unset ThumbFiles[*]
  360.     Column=0
  361.     fi
  362. done
  363. istrue Column && MakeRow "${ThumbFiles[@]}"
  364.  
  365. Pipeline="MakeBr ${RowFiles[*]}"
  366. istrue Colors && Pipeline="$Pipeline | ppmquant -fs $Colors"
  367. istrue Border && Pipeline="$Pipeline | pnmmargin -color $Background $Border"
  368. [ -n "$OutputConvert" ] && Pipeline="$Pipeline | $OutputConvert"
  369.  
  370. eval $Pipeline
  371.